#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
PErsonal Python Enhancements library (general purpose and data-mining)

Copyright (C) 2007-2009, Viktor Presovsky <vpresovsky@deloitteCE.com>
Copyright (C) 2003-2007, Viktor Presovsky <presovsky@gmail.com>
Copyright (C) 2009, Michal Sagat <msagat@deloitteCE.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

""" 
general soubroutines file 
last updated : 20091018-2119, by vip
"""

import glob
import os
import re
import string
import sys
import time
import shutil
import platform

# posix 2.4, nt 2.4
OSPYVER = "%s %s" % (os.name, platform.python_version()[:-2])
#print OSPYVER

import pepe.lambdas as lamb
#import pepe.p_dm.dama as dama
import pepe.p_dm.sdb as s
import pepe.p_sql.pg as pg
import pepe.p_txt.bigtxt as bt
import pepe.p_txt.txt_columns as tc
import pepe.p_utils.csv_sas as csvs
import pepe.p_utils.srchr as srchr
import pepe.p_utils.txt2pg as ppt
import pepe.p_utils.txtr as p_txtr
import pepe.p_utils.uid_uuid as uuid

zf9 = lambda x: string.zfill(str(x), 9)
# 2683099 -> *002.683.099*
x3x = lambda x: "*%s.%s.%s*" % (zf9(x)[:3], zf9(x)[3:6], zf9(x)[6:9])

fw_slash = lambda x: re.sub(r'\\', '/', x)

#print lamb.dtnow() # datetime stamp
timenow = lambda : time.strftime ("%Y%m%dT%H%M%S", time.localtime())
#print timenow()


def file_hash(ifile, type='sha256'):
    ''' calculate checksum for file
    '''
    import pepe.p_filesystem.dfstats as dfs
    
    rd = dfs.dfstats(ifile, options=[type], pprint=False)
    for f in sort_case_insensitive(rd.keys()):
        x = "%s *%s\n" % (rd[f][type], rd[f]['file_name'])
        return x

def strip_txt_columns(txt,cd=''):
    ''' '''
    line = re.sub('\n', '', txt)
    cols = string.split(line, cd)
    bare_cols = [string.strip(c) for c in cols]
    return string.join(bare_cols, cd) + '\n'

def sort_case_insensitive(stringList):
    ''' 
    http://code.activestate.com/recipes/170242/
    
    The default compare function used when sorting a list of strings uses the ordinal value 
    of the string characters for comparison. This results in the typical ASCII sort result 
    of 'B' < 'a'. If a user is going to see the list, it is generally better to do a case-insensitive comparison.
	
	Note: doesn't do locale-specific compare

    L = ['bank_ucty.txt', 'chs.dat#', 'dodav_pop.txt', 'dr_dokladu.txt', 'polozky.7z', 'uc_klice.txt', 'Dodavatele.txt', 'SR71.xls']
    
    print sorted(L)
    ['Dodavatele.txt', 'SR71.xls', 'bank_ucty.txt', 'chs.dat#', 'dodav_pop.txt', 'dr_dokladu.txt', 'polozky.7z', 'uc_klice.txt']
    
    print sort_case_insensitive(L)
    ['bank_ucty.txt', 'chs.dat#', 'dodav_pop.txt', 'Dodavatele.txt', 'dr_dokladu.txt', 'polozky.7z', 'SR71.xls', 'uc_klice.txt']
    '''
    tupleList = [(x.upper(), x) for x in stringList]
    tupleList.sort()
    return [x[1] for x in tupleList]

def findcoldelimiter_line(line):
    ''' guess what text file column delimiter is used 

    if cd == '': cd = findcoldelimiter_line(line)

    >>> findcoldelimiter_line("a|^b;^c~^d~")
    '^'
    '''
    c = 0; r = '' 
    for cs in [',', '\t', ';', '^', '~', '|']:
        if string.count(line, cs) > c:
            c = string.count(line, cs); r = cs
    return r

def findcoldelimiter(line):
    ''' maintained for backward compatibility purposes 
        use findcoldelimiter_line() in new projects
    '''
    return findcoldelimiter_line(line)

def findcoldelimiter_file(inputfile):
    ''' '''
    findcoldelimiter(line)

def lol_column(L, i):
    ''' return column from list-of-lists 
        L - list of lists
        i - column index
    >>> lol_column([[1,2],[3,4]], 1)
    [2, 4]
    '''
    return [x[i] for x in L]
    
def string2number(x):
    ''' convert string to number 

    >>> string2number('íáýsas,msmsas _'), string2number('wewšěě+š+ě+ěwewšěě+š+ě+ě')
    (0, 0)
    >>> string2number(''), string2number('-'), string2number('-0'), string2number('0-')
    (0, 0, 0, 0)
    >>> string2number('9.991.234,45-'), string2number('9,991,234.45-')
    (-9991234.4499999993, -9991234.4499999993)
    >>> string2number('-9991234,45-'), string2number('-9991234.45-')
    (-9991234.4499999993, -9991234.4499999993)
    >>> string2number('-9991234,45'), string2number('-9991234.45')
    (-9991234.4499999993, -9991234.4499999993)
    '''
    # handle following in some utf8 files ... 65Â 000,00
    x = re.sub('\xC2\xA0','', x)
    x = re.sub('Â ','', x)

    res = 0
    x = re.sub('[+ěĚšŠčČřŘžŽýÝáÁíÍéÉóÓúÚ a-zA-Z_]', '', x)

    # dot or coma : .., or ,,.
    doc = re.sub('(-| |\d)', '', x)
    if x in ('-', '0-', '-0', '.', ','): x = ''
    if len(x) == 0:
        return 0
    else:
        if len(doc) <> 0:
            # case 1.234,45-
            if doc[-1] == ',': res = float(re.sub(',', '.', re.sub('(\.|-)', '', x)))
            # case 1,234.45-
            if doc[-1] == '.': res = float(re.sub('(,|-)', '', x))
        else:
            res = float(x)
        if string.find(x, '-') <> -1: res = res*-1
        return res

if __name__ == "__main__":
    ''' '''
    import doctest
    doctest.testmod()
